<template>
  <el-upload
    ref="elUpload"
    :disabled="checkReturn"
    action="/"
    :show-file-list="false"
    :http-request="uploadFile"
    :before-upload="onBeforeUpload"
    drag
    :on-progress="uploadProgress"
    :on-success="uploadSuccess"
    :on-error="uploadError"
    :multiple="multiple"
    :limit="limit"
    :on-exceed="uploadExcedd"
    :on-change="uploadChange"
  >
    <slot></slot>
  </el-upload>
</template>
<script>
import { showLoading, hideLoading } from "@/utils/loading.js";
var reader = new FileReader();
import { tst } from "@/axios/api.js";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { uploads } from "@/axios/community.js";

import {
  defineComponent,
  reactive,
  toRefs,
  onUnmounted,
  onMounted,
  computed,
  getCurrentInstance,
  ref,
} from "vue";
import { ElMessage } from "element-plus";
export default defineComponent({
  emits: ["progressChange", "sucess", "fileQueued", "error"],
  props: {
    fileName: {
      type: String,
      default: "", //  UploadPictureModel 模型图片 community  社区  Events 活动 StableDiffusion SD Course 课程  用户信息 infoFile
    },
    sizeCheck: {
      type: Boolean,
      default: false,
    }, //特殊尺寸
    checkReturn: {
      type: Boolean,
      default: false,
    }, //上传是否禁用
    multiple: {
      type: Boolean,
      default: true,
    }, //是否支持多选
    limit: {
      type: Number,
      default: 1,
    }, //允许上传的最大数量
    type: {
      type: String,
      default: "png,jpg,jpeg",
    },
    multipleProgress: {
      type: Boolean,
      default: false,
    }, //是否多个进度
    isManual: {
      type: Boolean,
      default: false,
    }, //是否手动传入文件上传
    maxSize: {
      type: Number,
      default: 0,
    }, //单文件大小限制

    returnFile: {
      type: Boolean,
      default: false,
    }, //上传成功是否返回原文件信息
  },
  setup(props, { attrs, slots, emit }) {
    const router = useRouter();
    const { proxy } = getCurrentInstance();
    const store = useStore();
    const elUpload = ref(null);
    let data = reactive({
      uploadList: [],
    });

    // 文件状态改变
    let uploadChange = (val, valList) => {
      // console.log(val,valList,'xxx')
    };

    // 获取文件后缀
    let getFileType = (file) => {
      let fileType = file.name.split(".").slice(-1)[0].toLowerCase();
      return fileType;
    };

    // 文件超出限制
    let uploadExcedd = (e) => {
      if (e.length > props.limit) {
        return ElMessage.error("文件数量超出限制!");
      }
    };

    // 上传类型
    let accept = computed(() => {
      let uploadType = [];
      let typeList = props.type.split(",");
      uploadType = typeList.map((item) => {
        return item.toLowerCase();
      });
      return uploadType;
    });

    // 文件上传
    let uploadFile = (e) => {
      // console.log(e, "xxx");
      // console.log(data.uploadList,'dddd')
      // goalipay(e);
      tenupload(e);
      // e.onProgress();
    };
    // 特殊尺寸判断
    let size = () => {
      return new Promise((resolve, reject) => {
        let type;
        const maxSize = 4000; // 最大宽度为4000像素
        const maxSizeHeight = 3000; // 最大高度为3000像素
        const reader = new FileReader();
        reader.onload = () => {
          const image = new Image();
          image.onload = () => {
            const width = image.width;
            const height = image.height;
            if (width != maxSize || height != maxSizeHeight) {
              ElMessage.error("上传封面图尺寸不正确");
              type = false;
            } else {
              type = true;
            }
          };
        };
        console.log(type);
        resolve(type);
      });
    };
    // 文件上传前
    let onBeforeUpload = async (file) => {
      let fileType = getFileType(file);
      if (accept.value.indexOf(fileType) == -1) {
        ElMessage.error("文件格式不支持,请上传" + props.type + "格式文件");
        return false;
      }

      // 限制单文件大小
      if (props.maxSize) {
        let fileSize = file.size / 1024 / 1024;
        if (fileSize > props.maxSize) {
          ElMessage.error("上传的文件不能大于" + props.maxSize + "M");
          return false;
        }
      }

      let fileName = Date.now() + file.name; //文件名+时间戳 防止重复
      let newFile = new File([file], fileName, {
        type: file.type,
      });
      newFile.uploadLoading = true;
      data.uploadList.push(newFile);
      emit("fileQueued", newFile);
      // console.log(props.checkReturn);
      // if (props.checkReturn) {
      //   return;
      // }
      return newFile;
      // return false;  //返回false 终止上传
    };

    // 文件上传时
    let uploadProgress = (e) => {
      // console.log(e, "文件在上传");
    };

    // 文件上传成功
    let uploadSuccess = (e) => {
      console.log("文件上传成功", e);
      for (let i = 0; i < data.uploadList.length; i++) {
        let item = data.uploadList[i];
        if (e.name == item.name) {
          data.uploadList.splice(i, 1);
          break;
        }
      }
      setTimeout(() => {
        if (!data.uploadList.length) {
          elUpload.value.clearFiles();
        }
      }, 100);
      emit("sucess", e);
    };

    // 文件上传失败
    let uploadError = (err) => {
      console.log(err, "文件上传失败");
      emit("error", err);
    };
    let tenupload = (fin) => {
      // console.log(fin)
      let formData = new FormData();
      formData.append("file", fin.file);
      let headers = {};
      fin.headers.scene = 3;
      uploads(formData, headers)
        .then((res) => {
          hideLoading();
          if (props.returnFile) {
            emit("sucess", {
              name: fin.file.name,
              url: res.data,
              file: fin.file,
            });
          } else {
            emit("sucess", res.data);
          }
        })
        .catch((err) => {
          hideLoading();
        });
    };
    // 阿里云上传
    let goalipay = async (file) => {
      // console.log(file, "ffff");
      tst().then(async (res) => {
        let miyaodata = res.data;
        let fileData = file.file;
        const client = new OSS({
          // yourRegion填写Bucket所在地域。以华东1（杭州）为例，Region填写为oss-cn-hangzhou。
          region: "oss-cn-hangzhou",
          // 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
          accessKeyId: miyaodata.id,
          accessKeySecret: miyaodata.Secret,
          secure: true,
          // 从STS服务获取的安全令牌（SecurityToken）。
          stsToken: miyaodata.token,
          // 填写Bucket名称，例如examplebucket。
          bucket: "i-desai",
          dir: "upload/" + props.fileName + "/",
        });
        let name = "upload/" + props.fileName + "/" + fileData.name;
        // 获取DOM。
        const options = {
          // 获取分片上传进度、断点和返回值。
          progress: (p, cpt, res) => {
            // console.log(cpt,'ppppp')
            // if(!cpt.file.uploadLoading){
            //   emit("fileQueued", cpt.file);
            //   cpt.file.uploadLoading = true;
            // }
            let progress = (p * 100).toFixed(2);

            // 手动传入文件监听没有progress事件
            if (!props.isManual) {
              file.onProgress({ percent: progress });
            }

            // 如果要多个进度条 则会返回当前文件名称等信息
            if (props.multipleProgress) {
              // console.log(fileData,'cccc')
              emit("progressChange", {
                file: fileData,
                progress: Number(progress),
              });
            } else {
              emit("progressChange", Number(progress));
            }
          },
          // 设置并发上传的分片数量。
          parallel: 4,
          // 设置分片大小。默认值为1 MB，最小值为100 KB。
          partSize: 1024 * 1024 * 10,
          // headers,
          // 自定义元数据，通过HeadObject接口可以获取Object的元数据。
          meta: { year: 2020, people: "test" },
          mime: "text/plain",
        };

        try {
          // 分片上传。
          const res = await client.multipartUpload(name, fileData, {
            ...options,
          });

          let text;
          let fileType = getFileType(fileData);
          if (["png", "jpg", "jpeg"].indexOf(fileType) != -1) {
            text = await duqu(fileData);
            // console.log(text, "xxx");
          }
          let uploadSucessData = {
            name: fileData.name,
            url: " https://i-desai.oss-cn-hangzhou.aliyuncs.com/" + res.name,
            file: fileData,
            text,
          };

          // 手动传入文件上传没有success事件
          if (!props.isManual) {
            file.onSuccess(uploadSucessData);
          } else {
            uploadSuccess(uploadSucessData);
          }
          // emit("sucess", uploadSucessData);
        } catch (err) {
          // 手动传入文件没有err事件
          if (!props.isManual) {
            file.onError(err);
          }
        }
      });
    };

    // 读取文件元数据
    let duqu = async (file) => {
      let text = "";
      return new Promise((resolve, reject) => {
        try {
          reader.readAsArrayBuffer(file);
          reader.onload = async (event) => {
            // 读取文件数据
            const data = event.target.result;
            // 创建一个DataView对象
            const dataView = new DataView(data);

            // 检查文件是否是PNG格式
            const isPng = dataView.getUint32(0, false) === 0x89504e47;
            if (!isPng) {
              console.log("不是PNG格式的图像文件");
              resolve(text);
            }

            // 获取文件元数据信息
            let offset = 8;
            let chunkType, chunkSize, chunkData, crc;
            while (offset < dataView.byteLength) {
              chunkSize = dataView.getUint32(offset, false);
              offset += 4;
              chunkType = String.fromCharCode(
                dataView.getUint8(offset),
                dataView.getUint8(offset + 1),
                dataView.getUint8(offset + 2),
                dataView.getUint8(offset + 3)
              );
              offset += 4;
              if (chunkType === "tEXt") {
                const nullByteIndex = Array.from(
                  new Uint8Array(dataView.buffer.slice(offset + 1, offset + chunkSize))
                ).findIndex((b) => b === 0);
                const keyword = String.fromCharCode.apply(
                  null,
                  new Uint8Array(
                    dataView.buffer.slice(offset + 1, offset + nullByteIndex + 1)
                  )
                );
                text = String.fromCharCode.apply(
                  null,
                  new Uint8Array(
                    dataView.buffer.slice(offset + nullByteIndex + 2, offset + chunkSize)
                  )
                );
                // console.log(`PNG图像包含文本信息：${keyword}: ${text}`);
              }

              offset += chunkSize;
              crc = dataView.getUint32(offset, false);
              offset += 4;
            }
            // console.log(text,'xxxx')
            resolve(text);
          };
        } catch (error) {
          // console.log(error,'cuowwu')
          resolve(text);
        }
      });
    };

    return {
      tenupload,
      uploadChange,
      elUpload,
      uploadExcedd,
      uploadError,
      uploadSuccess,
      uploadProgress,
      onBeforeUpload,
      uploadFile,
      ...toRefs(data),
    };
  },
});
</script>
<style lang="scss" scoped>
:deep(.el-upload-dragger) {
  background-color: transparent;
  border: none;
  padding: 0;
}
</style>
